/*  This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation; either version 2.1 of the License, or (at
    your option) any later version.
    For more details, see the GNU Lesser General Public License (www.fsf.org
    or the COPYING file somewhere in the package)
 */

/*! @file OSGi/CGuard.inl
    @brief Class OSGi::CGuard inline methods.
    @author @ref Guillaume_Terrissol
    @date 27th December 2009 - 15th January 2014
    @note This file is distributed under the LGPL license.
    Refer to the file COPYING (or http://www.fsf.org) for more information.
 */

namespace OSGi
{
//------------------------------------------------------------------------------
//                           Constructors & Destructor
//------------------------------------------------------------------------------

    /*! Holds no resource.
     */
    template<class TC>
    CGuard<TC>::CGuard()
        : mFree{nullFree}
        , mResource{}
    { }


    /*! Use this overload to acquire a resource.
        @param pRes  Resource to acquire
        @param pFree @a pRes release function
     */
    template<class TC>
    CGuard<TC>::CGuard(TC* pRes, Free pFree)
        : mFree{pFree}
        , mResource{pRes}
    { }


    /*! Releases the resource.
     */
    template<class TC>
    CGuard<TC>::~CGuard()
    {
        reset();
    }


    /*! @param pThat Object to move
     */
    template<class TC>
    CGuard<TC>::CGuard(CGuard&& pThat)
        : mFree{nullFree}
        , mResource{}
    {
        std::swap(mFree,     pThat.mFree);
        std::swap(mResource, pThat.mResource);
    }


    /*! @param pThat Instance to assign to *<b>this</b>
        @return *<b>this</b>
     */
    template<class TC>
    CGuard<TC>& CGuard<TC>::operator=(CGuard&& pThat)
    {
        std::swap(mFree,     pThat.mFree);
        std::swap(mResource, pThat.mResource);

        return *this;
    }


    /*! Releases the resource.
     */
    template<class TC>
    void CGuard<TC>::reset()
    {
        if (mResource != nullptr)
        {
            mFree(mResource);
            mResource = nullptr;
        }
    }


//------------------------------------------------------------------------------
//                                    Access
//------------------------------------------------------------------------------

    /*! @return [a constant pointer to ] The resource
     */
    template<class TC>
    inline const TC* CGuard<TC>::operator->() const
    {
        return mResource;
    }


    /*! @return [a pointer to ] The resource
     */
    template<class TC>
    inline TC* CGuard<TC>::operator->()
    {
        return mResource;
    }


    /*! @return [a constant pointer to ] The resource
     */
    template<class TC>
    inline const TC* CGuard<TC>::get() const
    {
        return mResource;
    }


    /*! @return [a pointer to ] The resource
     */
    template<class TC>
    inline TC* CGuard<TC>::get()
    {
        return mResource;
    }


//------------------------------------------------------------------------------
//                                    Helper
//------------------------------------------------------------------------------

    /*! Does nothing to its parameter.
     */
    template<class TC>
    void CGuard<TC>::nullFree(TC*) { }
}
